{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 列表推导式"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "循环可以用来生成列表："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[100, 441, 16, 49, 144]\n"
     ]
    }
   ],
   "source": [
    "values = [10, 21, 4, 7, 12]\n",
    "squares = []\n",
    "for x in values:\n",
    "    squares.append(x**2)\n",
    "print squares"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "列表推导式可以使用更简单的方法来创建这个列表："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[100, 441, 16, 49, 144]\n"
     ]
    }
   ],
   "source": [
    "values = [10, 21, 4, 7, 12]\n",
    "squares = [x**2 for x in values]\n",
    "print squares"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "还可以在列表推导式中加入条件进行筛选。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "例如在上面的例子中，假如只想保留列表中不大于`10`的数的平方："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[100, 16, 49]\n"
     ]
    }
   ],
   "source": [
    "values = [10, 21, 4, 7, 12]\n",
    "squares = [x**2 for x in values if x <= 10]\n",
    "print squares"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "也可以使用推导式生成集合和字典："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "set([16, 49, 100])\n",
      "{10: 100, 4: 16, 7: 49}\n"
     ]
    }
   ],
   "source": [
    "square_set = {x**2 for x in values if x <= 10}\n",
    "print(square_set)\n",
    "square_dict = {x: x**2 for x in values if x <= 10}\n",
    "print(square_dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "再如，计算上面例子中生成的列表中所有元素的和："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "165\n"
     ]
    }
   ],
   "source": [
    "total = sum([x**2 for x in values if x <= 10])\n",
    "print(total)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "但是，**Python**会生成这个列表，然后在将它放到垃圾回收机制中（因为没有变量指向它），这毫无疑问是种浪费。\n",
    "\n",
    "为了解决这种问题，与xrange()类似，**Python**使用产生式表达式来解决这个问题："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "165\n"
     ]
    }
   ],
   "source": [
    "total = sum(x**2 for x in values if x <= 10)\n",
    "print(total)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "与上面相比，只是去掉了括号，但这里并不会一次性的生成这个列表。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "比较一下两者的用时："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "x = range(1000000)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 loops, best of 3: 3.86 s per loop\n"
     ]
    }
   ],
   "source": [
    "%timeit total = sum([i**2 for i in x])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 loops, best of 3: 2.58 s per loop\n"
     ]
    }
   ],
   "source": [
    "%timeit total = sum(i**2 for i in x)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
